Monitorización y Gestión de Configuraciones: Sinergia entre LibreNMS y Oxidized
En casi cualquier entorno medianamente serio, da igual que sea una pyme con tres racks o un CPD con varias sedes interconectadas, hay un momento que todos los que trabajamos en infraestructura hemos vivido. Algo deja de funcionar. Puede ser una caída intermitente en una VLAN, un firewall que empieza a comportarse raro o simplemente un core que, sin previo aviso, decide no reenviar tráfico como debería.
Entonces empieza el ritual. Te conectas por SSH, revisas logs, consultas métricas históricas, y, casi siempre, surge la misma pregunta incómoda: “¿Quién tocó esto y cuándo?”. El silencio en el equipo suele ser bastante elocuente.
Ahí es donde empiezan a cobrar sentido herramientas como LibreNMS y Oxidized. No como piezas aisladas, sino como parte de una estrategia mínima de higiene operativa. Porque monitorizar sin trazabilidad de configuración se queda corto. Y hacer backups de configuración sin visibilidad de estado, también.
Lo interesante es que ambas soluciones, además de ser open source, encajan muy bien en entornos donde el presupuesto no es infinito pero la exigencia técnica sí lo es. Y eso, en el mundo TIC, es bastante habitual.
Por qué la integración LibreNMS + Oxidized es el estándar en NetOps
La unión de ambos crea una correlación directa entre rendimiento y configuración. En el panel de LibreNMS, el administrador no solo ve que un enlace está saturado, sino que, gracias a Oxidized, puede ver instantáneamente si alguien cambió una política de QoS en ese mismo instante.
Esta sinergia elimina los silos de información, LibreNMS vigila el "cómo funciona" el equipo, mientras Oxidized vigila el "qué tiene escrito" dentro.
Vamos a explicar más a fondo cada producto y os explicamos como instalarlos bajo Docker.
¿Qué es LibreNMS? La Navaja Suiza del Monitoreo de Red Open Source
LibreNMS es un sistema de gestión y monitorización de redes (NMS) basado en PHP/MySQL, diseñado bajo una filosofía de código abierto total. A diferencia de herramientas propietarias rígidas, LibreNMS destaca por su capacidad de auto-descubrimiento, lo que minimiza la carga administrativa al desplegar inventarios complejos.
Utiliza el protocolo SNMP como motor principal, pero su verdadera potencia reside en su flexibilidad. Es capaz de integrarse con protocolos como OSPF, BGP y servicios de telemetría, proporcionando una visibilidad de 360 grados sobre el tráfico, la salud del hardware (sensores de temperatura, ventiladores, voltajes) y la disponibilidad de servicios.
- Su arquitectura basada en el fork de Observium lo hace compatible con una base de datos de dispositivos (MIBs) inmensa, siendo la alternativa preferida para quienes buscan observabilidad sin costes de licencia por nodo.
Oxidized: El Centinela de las Configuraciones y el Versionado Git
Oxidized no es simplemente una herramienta de backup, es un motor de recolección de estados de configuración para dispositivos de red. Escrito en Ruby, nace para resolver las limitaciones del antiguo RANCID, ofreciendo una integración nativa con repositorios Git.
Su función crítica es conectarse de forma programada a routers, switches y firewalls para extraer el archivo de configuración activo. Al integrarlo con Git, permite transformar el caos de los cambios manuales en un historial de auditoría inalterable. Cada vez que un técnico modifica una VLAN o una regla de acceso, Oxidized detecta el cambio, lo versiona y permite comparar (diff) el estado actual con cualquier punto del pasado.
- Su ligereza y su capacidad para manejar cientos de sistemas operativos de red (Cisco, Juniper, Mikrotik, Fortinet) lo convierten en la pieza de gobierno de configuración indispensable para cumplir con normativas de ciberseguridad y recuperación ante desastres (Disaster Recovery).
Instalación Oxidized + LibreNMS bajo Docker
Usaré Portainer para desplegar los contenedores. Lo primero es crear la estructura donde residirán los contenedores y sus datos persistentes:

En oxikixed, carpeta config, creamos un fichero router.db con un contenido preliminar, por ejemplo:
192.168.2.69:routeros
Y también en dicha carpeta un fichero config con el siguiente contenido:
---# Oxidized configrest: 0.0.0.0:8888 # Web UI y API
username: oxidadmin # Usuario web Oxidized
password: strongpassword123 # Contraseña web Oxidized
interval: 3600 # Cada horause_syslog: falsedebug: falsethreads: 10
timeout: 20retries: 3prompt: !ruby/regexp /^([\w.@-]+[#>]\s?)$/groups:
mikrotik: username: oxidized password: MikrotikStrongPass
model: routerosmodels: {}source: default: http http:
url: http://nascasika.negu.local:8085/api/v0/oxidized headers:
X-Auth-Token: TOKEN-ID map: name: hostname model: os
group: groupoutput: default: git git: user: Oxidized
email: oxidized@nascasika.local
repo: /home/oxidized/.config/oxidized/repos single_repo: truehooks:
post_store: type: exec events: [node_success]
cmd: "echo 'Backup completed for {{ node }}'"
Genero un stack para librenms y otro para Oxidized:
Stack Portainer Librenms
Usaré Volume2 para las carpetas persistentes.
version: "3.8"services: db: image: mariadb:10.6
container_name: LibreNMS-DB restart: unless-stopped command:
- mariadbd - --innodb-file-per-table=1
- --lower-case-table-names=0 - --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci environment:
TZ: Europe/Madrid MYSQL_ROOT_PASSWORD: rootpass
MYSQL_DATABASE: librenms MYSQL_USER: librenms
MYSQL_PASSWORD: librenmspass volumes:
- /volume2/Docker/librenms/db:/var/lib/mysql:rw networks:
- librenms_net redis: image: redis:7.2-alpine
container_name: LibreNMS_REDIS restart: unless-stopped environment:
TZ: Europe/Madrid volumes:
- /volume2/Docker/librenms/redis:/data:rw networks: - librenms_net
librenms: image: librenms/librenms:latest container_name: LibreNMS
restart: unless-stopped hostname: librenms cap_add: - NET_ADMIN
- NET_RAW ports: - "8085:8000" depends_on: - db
- redis volumes: - /volume2/Docker/librenms/data:/data:rw
environment: TZ: Europe/Madrid PUID: 1000 PGID: 1000
DB_HOST: db DB_NAME: librenms DB_USER: librenms
DB_PASSWORD: librenmspass CACHE_DRIVER: redis
SESSION_DRIVER: redis REDIS_HOST: redis REDIS_PORT: 6379
LIBRENMS_SNMP_COMMUNITY: librenmsdocker networks: - librenms_net
dispatcher: image: librenms/librenms:latest
container_name: LibreNMS-DISPATCHER restart: unless-stopped
hostname: librenms-dispatcher cap_add: - NET_ADMIN - NET_RAW
depends_on: - librenms - redis - db volumes:
- /volume2/Docker/librenms/data:/data:rw environment:
TZ: Europe/Madrid PUID: 1000 PGID: 1000
APP_ROLE: dispatcher DISPATCHER_NODE_ID: dispatcher1
SIDECAR_DISPATCHER: 1 DB_HOST: db DB_NAME: librenms
DB_USER: librenms DB_PASSWORD: librenmspass REDIS_HOST: redis
CACHE_DRIVER: redis networks: - librenms_net scheduler:
image: librenms/librenms:latest container_name: LibreNMS-SCHEDULER
restart: unless-stopped hostname: librenms-scheduler depends_on:
- librenms - redis - db volumes:
- /volume2/Docker/librenms/data:/data:rw environment:
TZ: Europe/Madrid PUID: 1000 PGID: 1000 APP_ROLE: scheduler
DB_HOST: db DB_NAME: librenms DB_USER: librenms
DB_PASSWORD: librenmspass REDIS_HOST: redis CACHE_DRIVER: redis
networks: - librenms_net syslogng: image: librenms/librenms:latest
container_name: LibreNMS_SYSLOGNG restart: unless-stopped
hostname: librenms-syslogng cap_add: - NET_ADMIN - NET_RAW
depends_on: - librenms - redis - db ports:
- "514:514/tcp" - "514:514/udp" volumes:
- /volume2/Docker/librenms/data:/data:rw environment:
TZ: Europe/Madrid PUID: 1000 PGID: 1000 APP_ROLE: syslogng
SIDECAR_SYSLOGNG: 1 DB_HOST: db DB_NAME: librenms
DB_USER: librenms DB_PASSWORD: librenmspass REDIS_HOST: redis
CACHE_DRIVER: redis networks: - librenms_net snmptrapd:
image: librenms/librenms:latest container_name: LibreNMS_SNMPTRAPD
restart: unless-stopped hostname: librenms-snmptrapd cap_add:
- NET_ADMIN - NET_RAW depends_on: - librenms - redis
- db ports: - "162:162/tcp" - "162:162/udp" volumes:
- /volume2/Docker/librenms/data:/data:rw environment:
TZ: Europe/Madrid PUID: 1000 PGID: 1000 APP_ROLE: snmptrapd
SIDECAR_SNMPTRAPD: 1 DB_HOST: db DB_NAME: librenms
DB_USER: librenms DB_PASSWORD: librenmspass REDIS_HOST: redis
CACHE_DRIVER: redis networks: - librenms_netnetworks:
librenms_net: driver: bridge
Una vez lanzado, podemos conectarnos a http://IP-NAS:8085 (el puerto 8000 lo tenía ocupado):

Completamos los datos de usuario, contraseña y email. Pulsamos Finish Install:

Ahora podemos validar la instalación o ir directamente al Dashboard:

Puede ser que tengáis que hacer el usuario a mano, os dejo como hacerlo conectándoos al contenedor LibreNMS:

En la primera conexión podréis editar con widgets el dashboard a vuestro gusto (alertas, historial, estados...):

Con esto ya tenemos librenms arriba.
Stack Portainer Oxidized
Creamos otro stack para Oxidized, estarán en la misma red y tendrá datos persistentes:

version: "3.8"services: oxidized: image: oxidized/oxidized:latest
container_name: oxidized restart: unless-stopped ports:
- "8888:8888" environment: TZ: Europe/Madrid volumes:
- /volume2/Docker/oxidized/config:/home/oxidized/.config/oxidized
- /volume2/Docker/oxidized/repos:/home/oxidized/.config/oxidized/repos
networks: - librenms_librenms_netnetworks: librenms_librenms_net:
external: true
Lanzamos el Deploy Stack y intentamos conectarnos al interfaz web "http://IP_NAS:8888" :

Ya tenemos LibreNMS y Oxidized creados, vamos a integrarlos.
Integración LibreNMS y Oxidized
LibreNMS se integra con Oxidized para mostrar las configuraciones de los equipos.
Estas opciones controlan si LibreNMS permite ver las versiones antiguas, si puede organizar los dispositivos en grupos, y si debe avisar a Oxidized cada vez que se añade un equipo nuevo.
Activarlas hace que LibreNMS y Oxidized trabajen juntos automáticamente, sin que el administrador tenga que editar archivos manualmente.
Pulsamos en "Global Settings" desde la consola de LibreNMS:

Pestaña "External" -> "Oxidizied". Marcamos las siguientes configuraciones:
- Enable config versioning Access: Activa la posibilidad de ver todas las versiones antiguas de la configuración del dispositivo guardadas por Oxidized.
- Enable the return of groups to Oxidized: Si lo activas, LibreNMS envía a Oxidized a qué grupo pertenece cada dispositivo (como switches o routers). Oxidized lo usará para organizar mejor las configuraciones.
- Reload Oxidized nodes list, each time a device is added: Si lo activas, cada vez que añades un dispositivo en LibreNMS, éste avisa automáticamente a Oxidized para que lo añada a su lista.

Creamos un token en Librenms. Configuración -> API -> API Settings:

Create API access token:


En el fichero "config" de Oxidized deberéis sustituir:


Por:

En mi caso:

Reiniciamos el contenedor.
Y validamos con el siguiente comando desde el contenedor de Oxidized, que debería entregaros el listado:
curl -H "X-Auth-Token: TU_TOKEN" http://librenms/api/v0/oxidized

En el contenedor de LibreNMS, adicionalmente lanzamos estos comandos:
su - librenms
cd /opt/librenms
lnms config:set oxidized.enabled true
lnms config:set oxidized.url http://oxidized:8888
lnms config:set oxidized.features.versioning true
lnms config:set oxidized.group_support true
Para limpiar la caché:
php artisan config:clear
php artisan cache:clear

Agregar Router Mikrotik a LibreNMS
Ahora vamos a agregar un router Mikrotik.
Desde la gestión de nuestro Router, IP -> SNMP:

Configuramos la community y el destino. Para el ejemplo, al ser laboratorio, usaré SNMP v2c, pero en producción es recomendable usar SNMP v3:


Podéis validar la configuración desde dentro del docker de LibreNMS vía consola (me dejé la variable DISPATCHER_NODE_ID: 1 en un principio):
- Nos conectamos con el usuario librenms y no root. "su - librenms"
- Nos colocamos en el directorio: "cd /opt/librenms"
- Y lanzamos el script de validación: "./validate.php"

Al estar montado de Docker, es posible que la IP no sea la del NAS, y necesitemos agregar la red del contenedor Docker en el Mikrotik. Probar:
snmpwalk -v2c -c public 192.168.2.69
![]()
Verificáis la red que usa el contenedor:

Y corregís los permisos en Mikrotik (para pruebas podéis abrir toda la red, pero luego restringir):
/snmp community set [find name=public] addresses=172.27.0.0/16
Es probable, si usas el firewall de Mikrotik, que tengas que abrir una regla específica. Os dejo el comando:
/ip firewall filter add chain=input protocol=udp dst-port=161 src-address=192.168.2.148 action=accept comment="SNMP LibreNMS"
O
/ip firewall filter add chain=input protocol=udp dst-port=161 src-address=172.27.0.4 action=accept comment="SNMP LibreNMS"
Y una restrictiva para el resto de orígenes:
/ip firewall filter add chain=input protocol=udp dst-port=161 action=drop

Desde la consola de LibreNMS agregamos un nuevo dispositivo:

Introducimos los datos del router Mikrotik y pulsamos "Add Device":

En unos segundos veremos nuestro equipo conectado:

Ahora empezaremos a recoger datos, y si la integración con Oxidized es correcta, se agregarán automáticamente al sistema, simplificando la operativa:

Monitorización profesional con LibreNMS y Oxidized
La integración exitosa de LibreNMS y Oxidized representa un salto cualitativo en la gestión de infraestructuras de red. Al centralizar la monitorización de rendimiento mediante el polling distribuido y automatizar la extracción de configuraciones, no solo ganamos visibilidad en tiempo real, sino también una red de seguridad ante desastres o errores de configuración manuales.
Como hemos visto, la clave en entornos de virtualización y contenedores reside en la correcta orquestación de servicios como Redis y el Dispatcher Service. Una vez establecida esta base sólida y validada la comunicación con nuestros activos, en este ejemplo, un router MikroTik, el sistema deja de ser una simple herramienta de consulta para convertirse en un componente crítico de la gobernanza IT.
Sin embargo, el despliegue no termina aquí. El flujo de trabajo óptimo en la administración moderna de sistemas exige un control de versiones riguroso. El siguiente paso lógico es la integración con Git.
Al exportar los backups de Oxidized a un repositorio centralizado, transformamos los archivos de configuración en código auditable. Esto nos permite:
- Mantener un historial de cambios detallado (Versionado).
- Facilitar la recuperación ante desastres con trazabilidad completa.
- Sentar las bases para la automatización mediante metodologías NetDevOps.
La monitorización nos dice que el servicio está caído, la gestión de configuraciones nos dice por qué cambió y cómo restaurarlo. En próximas entregas, profundizaremos en la automatización de este ciclo de vida mediante el uso de repositorios Git.
Fin del Artículo. ¡Cuéntanos algo en los Comentarios!



